export default class Wil {
	constructor() {
		this._wilBuffer = null
		this._wixBuffer = null
		this._wilDv = null
		this._wixDv = null
		this._imageIndexs = []
		this._imageInfos = []
		this._imageCount = 0
		this._colorCount = 0
		this._paletteSize = 0
		this._paletteLength = 0
		this._palette = ''
	}

	readWil(wil) {
		this._wilBuffer = wil
		this._wilDv = new DataView(this._wilBuffer)
		this._imageCount = this._wilDv.getUint32(44, true) //读取4字节转成int ,图片长度
		this._colorCount = this._wilDv.getUint32(48, true) //读取4字节 色深度
		this._paletteSize = this._wilDv.getUint32(52, true)
		this._paletteLength = Math.floor(this._paletteSize / 4) //调色板大小
		this._palette = this._readPalatte()// 读取调色板数据
		return this
	}

	readWix(wix) {
		this._wixBuffer = wix
		this._wixDv = new DataView(this._wixBuffer)
		let offset = 48
		this._imageIndexs = []
		for (let i = 0; i < this._imageCount; i++) {
			this._imageIndexs.push(this._wixDv.getUint32(offset, true))// 之后每个4字节都是图片地址索引，fseek 的参数
			offset += 4
		}
		return this
	}

	getInfo(id = 0) {
		if(!this._imageIndexs[id]){
			return false
		}
		if(!this._imageInfos[id]){
			this._imageInfos[id] = this._formatInfo(this._imageIndexs[id], this._getBit())
		}
		return this._imageInfos[id]
	}

	getImage(id = 0) {
		if(!this._imageIndexs[id]){
			return false
		}
		if(!this._imageInfos[id]){
			this._imageInfos[id] = this._formatInfo(this._imageIndexs[id], this._getBit())
		}
		let img = new Image()
		img.src = 'data:image/bmp;base64,' + btoa(String.fromCharCode(...this._imageInfos[id].buffer))
		return img
	}

	//设置调色板数据，这里主要是处理黑色
	_readPalatte() {
		let str = ''
		for (let i = 0; i < this._paletteLength; i++) {
			let byteArgb = [
				this._wilDv.getUint8(56 + i * 4, true),
				this._wilDv.getUint8(57 + i * 4, true),
				this._wilDv.getUint8(58 + i * 4, true),
				this._wilDv.getUint8(59 + i * 4, true)
			]
			if (byteArgb[2] == 0 && byteArgb[1] == 0 && byteArgb[0] == 0) {
				byteArgb[3] = 0
			} else {
				byteArgb[3] = 255
			}
			str += String.fromCharCode(byteArgb[0]) + String.fromCharCode(byteArgb[1]) + String.fromCharCode(byteArgb[2]) + String.fromCharCode(byteArgb[3])
		}
		return str
	}

	_mergeArrayBuffer(...arrays) {
		let totalLen = 0
		for (let i = 0; i < arrays.length; i++) {
			arrays[i] = new Uint8Array(arrays[i]) //全部转成Uint8Array
			totalLen += arrays[i].length
		}
		let res = new Uint8Array(totalLen)
		let offset = 0
		for (let arr of arrays) {
			res.set(arr, offset)
			offset += arr.length
		}
		return res.buffer
	}

	_toBMP(buffer, width, height) {
		// 位图文件头
		let fileHeader = new ArrayBuffer(14)
		let fileHeaderDv = new DataView(fileHeader)
		fileHeaderDv.setUint8(0, 'B'.charCodeAt(0), true)
		fileHeaderDv.setUint8(1, 'M'.charCodeAt(0), true)
		fileHeaderDv.setUint32(2, 54 + this._palette.length + buffer.byteLength, true)
		fileHeaderDv.setUint16(6, 0, true)
		fileHeaderDv.setUint16(8, 0, true)
		fileHeaderDv.setUint32(10, 54 + this._palette.length, true)

		// 位图信息头
		let infoHeader = new ArrayBuffer(40)
		let infoHeaderDv = new DataView(infoHeader)
		infoHeaderDv.setUint32(0, 40, true)
		infoHeaderDv.setUint32(4, width, true)
		infoHeaderDv.setUint32(8, height, true)
		infoHeaderDv.setUint16(12, 1, true)
		infoHeaderDv.setUint16(14, this._getBit(), true)
		infoHeaderDv.setUint32(18, 0, true)
		infoHeaderDv.setUint32(20, buffer.byteLength, true)
		infoHeaderDv.setUint32(24, 0, true)
		infoHeaderDv.setUint32(28, 0, true)
		infoHeaderDv.setUint32(32, this._paletteLength, true)
		infoHeaderDv.setUint32(36, 0, true)

		let paletteBuffer = this._str2ab(this._palette)

		return new Uint8Array(this._mergeArrayBuffer(fileHeader, infoHeader, paletteBuffer, buffer))
	}

	_formatImageInfos() {
		this._imageInfos = []
		for (let i = 0; i < this._imageCount; i++) {
			let imageInfo = this._formatInfo(this._imageIndexs[i], this._getBit())
			this._imageInfos.push(imageInfo)
		}
	}

	_formatInfo(offset, bit) {
		let dataObj = {
			width: 0,
			height: 0,
			offsetX: 0,
			offsetY: 0,
			size: 0,
			bit: bit,
			buffer: null
		}
		if (offset + 8 >= this._wilBuffer.byteLength) {
			return dataObj
		}
		dataObj.width = this._wilDv.getUint16(offset, true)// 宽
		dataObj.height = this._wilDv.getUint16(offset + 2, true)// 高
		dataObj.offsetX = this._wilDv.getUint16(offset + 4, true)// x位移
		dataObj.offsetY = this._wilDv.getUint16(offset + 6, true)// y位移
		dataObj.size = dataObj.width * dataObj.height * dataObj.bit / 8
		dataObj.buffer = this._toBMP(this._wilBuffer.slice(offset + 8, offset + 8 + dataObj.size), dataObj.width, dataObj.height)
		return dataObj
	}

	_getBit() {
		if (this._colorCount == 256) {
			return 8
		} else if (this._colorCount == 65536) {
			return 16
		} else if (this._colorCount == 16777216) {
			return 24
		} else {
			return 32
		}
	}

	_str2ab(str) {
		var buf = new ArrayBuffer(str.length); // 每个字符占用2个字节
		var bufView = new Uint8Array(buf);
		for (var i = 0, strLen = str.length; i < strLen; i++) {
			bufView[i] = str.charCodeAt(i);
		}
		return buf;
	}

	_buf2hex(buffer) {
		return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
	}

}